﻿using System.Diagnostics.CodeAnalysis;
using AutoMapper;
using Steve.UI.Administration.Models;
using Microsoft.ComponentModel.Composition.Extensions.Web;

namespace Steve.UI.Administration
{
    //TODO: move AutoMapper stuff to some sort of automatic discovery / scan process...
    //TODO: thread safety?
    [SuppressMessage("Microsoft.Maintainability", "CA1505:AvoidUnmaintainableCode")]
    public static class SteveAdministrationSite
    {
        public static void Initialize(ScopedContainerManager container)
        {
            SetupAutoMapper(container);
        }

        [SuppressMessage("Microsoft.Maintainability", "CA1506:AvoidExcessiveClassCoupling")]
        [SuppressMessage("Microsoft.Maintainability", "CA1505:AvoidUnmaintainableCode", Justification = "Only run once, complex due to lambdas in syntax")]
        [SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Justification="Only run once, complex due to lambdas in syntax")]
        internal static void SetupAutoMapper(ScopedContainerManager container)
        {
            Mapper.CreateMap<RewriteUrl, ExistingUrlRewriteDetailModel>()
                .ForMember(dest => dest.NextRevisionComment, opt => opt.Ignore())

                .ForMember(dest => dest.Url, opt => opt.MapFrom(src => src.ToUri(container)));

            Mapper.CreateMap<NewUrlRewriteDetailModel, RewriteUrl>()
                .ForMember(dest => dest.Id, opt => opt.Ignore())
                .ForMember(dest => dest.SystemName, opt => opt.Ignore())
                .ForMember(dest => dest.ExternalId, opt => opt.Ignore())
                .ForMember(dest => dest.LatestRevisionNumber, opt => opt.Ignore())
                .ForMember(dest => dest.RevisionNumber, opt => opt.Ignore())
                .ForMember(dest => dest.CreateDate, opt => opt.Ignore())
                .ForMember(dest => dest.RevisionMembershipId, opt => opt.Ignore())
                .ForMember(dest => dest.CreateMembershipId, opt => opt.Ignore())
                .ForMember(dest => dest.RevisionDate, opt => opt.Ignore())
                .ForMember(dest => dest.SiteName, opt => opt.Ignore())

                .ForMember(dest => dest.IsNew, opt => opt.UseValue(true))

                .ForMember(dest => dest.RevisionComment, opt => opt.MapFrom(src => src.NextRevisionComment))
                .ForMember(dest => dest.IsSecure, opt => opt.MapFrom(src => src.Url.Scheme == "https"))
                .AfterMap((src, dest) =>
                {
                    var data = container.GetExportedValue<SiteExplorerRepository>();
                    var site = data.GetSites().NavigateToSite(src.Url);

                    if (site != null)
                    {
                        dest.SiteName = site.SiteName;
                    }

                    dest.Url = src.Url.PathAndQuery;
                });

            Mapper.CreateMap<ExistingUrlRewriteDetailModel, RewriteUrl>()
                .ForMember(dest => dest.Id, opt => opt.Ignore())
                .ForMember(dest => dest.Url, opt => opt.Ignore())
                .ForMember(dest => dest.SiteName, opt => opt.Ignore())
                .ForMember(dest => dest.SystemName, opt => opt.Ignore())
                .ForMember(dest => dest.ExternalId, opt => opt.Ignore())
                .ForMember(dest => dest.LatestRevisionNumber, opt => opt.Ignore())
                .ForMember(dest => dest.RevisionNumber, opt => opt.Ignore())
                .ForMember(dest => dest.CreateDate, opt => opt.Ignore())
                .ForMember(dest => dest.RevisionMembershipId, opt => opt.Ignore())
                .ForMember(dest => dest.CreateMembershipId, opt => opt.Ignore())
                .ForMember(dest => dest.RevisionDate, opt => opt.Ignore())

                .ForMember(dest => dest.IsNew, opt => opt.UseValue(false))

                .ForMember(dest => dest.RevisionComment, opt => opt.MapFrom(src => src.NextRevisionComment));


            Mapper.CreateMap<Site, NewSiteDetailModel>();
            Mapper.CreateMap<Site, ExistingSiteDetailModel>();

            Mapper.CreateMap<ExistingSiteDetailModel, Site>()
                .ForMember(dest => dest.CreateDate, opt => opt.Ignore())
                .ForMember(dest => dest.CreateMembershipId, opt => opt.Ignore())
                .ForMember(dest => dest.RevisionDate, opt => opt.Ignore())
                .ForMember(dest => dest.RevisionMembershipId, opt => opt.Ignore())
                .ForMember(dest => dest.IsNew, opt => opt.UseValue(false));

            Mapper.CreateMap<NewSiteDetailModel, Site>()
                .ForMember(dest => dest.CreateDate, opt => opt.Ignore())
                .ForMember(dest => dest.CreateMembershipId, opt => opt.Ignore())
                .ForMember(dest => dest.RevisionDate, opt => opt.Ignore())
                .ForMember(dest => dest.RevisionMembershipId, opt => opt.Ignore())
                .ForMember(dest => dest.IsNew, opt => opt.UseValue(true));

            Mapper.CreateMap<SiteUrl, ExistingSiteUrlDetailModel>()
                .ForMember(dest => dest.Rewrites, opt => opt.Ignore())
                .ForMember(dest => dest.NextRevisionComment, opt => opt.Ignore())
                
                .ForMember(dest => dest.Url, opt => opt.MapFrom(src => src.ToUri(container)));

            Mapper.CreateMap<NewSiteUrlDetailModel, SiteUrl>()
                .ForMember(dest => dest.Id, opt => opt.Ignore())
                .ForMember(dest => dest.Url, opt => opt.Ignore())
                .ForMember(dest => dest.SiteName, opt => opt.Ignore())
                .ForMember(dest => dest.SystemName, opt => opt.Ignore())
                .ForMember(dest => dest.LatestRevisionNumber, opt => opt.Ignore())
                .ForMember(dest => dest.RevisionNumber, opt => opt.Ignore())
                .ForMember(dest => dest.PageTitle, opt => opt.Ignore())
                .ForMember(dest => dest.PageMetaDescription, opt => opt.Ignore())
                .ForMember(dest => dest.PageMetaKeywords, opt => opt.Ignore())
                .ForMember(dest => dest.ExternalId, opt => opt.Ignore())
                .ForMember(dest => dest.CreateDate, opt => opt.Ignore())
                .ForMember(dest => dest.RevisionMembershipId, opt => opt.Ignore())
                .ForMember(dest => dest.CreateMembershipId, opt => opt.Ignore())
                .ForMember(dest => dest.RevisionDate, opt => opt.Ignore())

                .ForMember(dest => dest.IsNew, opt => opt.UseValue(true))

                .ForMember(dest => dest.RevisionComment, opt => opt.MapFrom(src => src.NextRevisionComment))
                .ForMember(dest => dest.IsSecure, opt => opt.MapFrom(src => src.Url.Scheme == "https"))
                .AfterMap((src, dest) =>
                {
                    var data = container.GetExportedValue<SiteExplorerRepository>();
                    var site = data.GetSites().NavigateToSite(src.Url);

                    if (site != null)
                    {
                        dest.SiteName = site.SiteName;
                    }

                    dest.Url = src.Url.PathAndQuery;
                });

            Mapper.CreateMap<ExistingSiteUrlDetailModel, SiteUrl>()
                .ForMember(dest => dest.Id, opt => opt.Ignore())
                .ForMember(dest => dest.Url, opt => opt.Ignore())
                .ForMember(dest => dest.SiteName, opt => opt.Ignore())
                .ForMember(dest => dest.SystemName, opt => opt.Ignore())
                .ForMember(dest => dest.LatestRevisionNumber, opt => opt.Ignore())
                .ForMember(dest => dest.RevisionNumber, opt => opt.Ignore())
                .ForMember(dest => dest.PageTitle, opt => opt.Ignore())
                .ForMember(dest => dest.PageMetaDescription, opt => opt.Ignore())
                .ForMember(dest => dest.PageMetaKeywords, opt => opt.Ignore())
                .ForMember(dest => dest.ExternalId, opt => opt.Ignore())
                .ForMember(dest => dest.CreateDate, opt => opt.Ignore())
                .ForMember(dest => dest.RevisionMembershipId, opt => opt.Ignore())
                .ForMember(dest => dest.CreateMembershipId, opt => opt.Ignore())
                .ForMember(dest => dest.RevisionDate, opt => opt.Ignore())

                .ForMember(dest => dest.IsNew, opt => opt.UseValue(false))

                .ForMember(dest => dest.RevisionComment, opt => opt.MapFrom(src => src.NextRevisionComment))
                .ForMember(dest => dest.IsSecure, opt => opt.MapFrom(src => src.Url.Scheme == "https"));

            Mapper.CreateMap<NewCategoryDetailModel, Category>()
                .ForMember(dest => dest.CreateDate, opt => opt.Ignore())
                .ForMember(dest => dest.RevisionMembershipId, opt => opt.Ignore())
                .ForMember(dest => dest.CreateMembershipId, opt => opt.Ignore())
                .ForMember(dest => dest.RevisionDate, opt => opt.Ignore())

                .ForMember(dest => dest.IsNew, opt => opt.UseValue(true));

            Mapper.CreateMap<ExistingCategoryDetailModel, Category>()
                .ForMember(dest => dest.CreateDate, opt => opt.Ignore())
                .ForMember(dest => dest.RevisionMembershipId, opt => opt.Ignore())
                .ForMember(dest => dest.CreateMembershipId, opt => opt.Ignore())
                .ForMember(dest => dest.RevisionDate, opt => opt.Ignore())

                .ForMember(dest => dest.IsNew, opt => opt.UseValue(false));

            Mapper.CreateMap<Category, ExistingCategoryDetailModel>();

            Mapper.CreateMap<ExistingContentDetailModel, Content>()
                .ForMember(dest => dest.ContentTypeName, opt => opt.Ignore())
                .ForMember(dest => dest.PublicationDate, opt => opt.Ignore())
                .ForMember(dest => dest.Publisher, opt => opt.Ignore())
                .ForMember(dest => dest.ApprovalDate, opt => opt.Ignore())
                .ForMember(dest => dest.ApprovalMembershipId, opt => opt.Ignore())
                .ForMember(dest => dest.ContentDataId, opt => opt.Ignore())
                .ForMember(dest => dest.Author, opt => opt.Ignore())
                .ForMember(dest => dest.Id, opt => opt.Ignore())
                .ForMember(dest => dest.Language, opt => opt.Ignore())
                .ForMember(dest => dest.SystemName, opt => opt.Ignore())
                .ForMember(dest => dest.LatestRevisionNumber, opt => opt.Ignore())
                .ForMember(dest => dest.LatestApprovedRevisionNumber, opt => opt.Ignore())
                .ForMember(dest => dest.RevisionNumber, opt => opt.Ignore())
                .ForMember(dest => dest.ExternalId, opt => opt.Ignore())
                .ForMember(dest => dest.CreateDate, opt => opt.Ignore())
                .ForMember(dest => dest.RevisionMembershipId, opt => opt.Ignore())
                .ForMember(dest => dest.CreateMembershipId, opt => opt.Ignore())
                .ForMember(dest => dest.RevisionDate, opt => opt.Ignore())
                .ForMember(dest => dest.Height, opt => opt.Ignore())
                .ForMember(dest => dest.Width, opt => opt.Ignore())
                .ForMember(dest => dest.MimeType, opt => opt.Ignore())
                .ForMember(dest => dest.MimeSubtype, opt => opt.Ignore())
                .ForMember(dest => dest.SiteName, opt => opt.Ignore())
                .ForMember(dest => dest.Url, opt => opt.Ignore())
                .ForMember(dest => dest.IsSecure, opt => opt.Ignore())
                .ForMember(dest => dest.DefaultAuthority, opt => opt.Ignore())

                .ForMember(dest => dest.IsNew, opt => opt.UseValue(false))

                .ForMember(dest => dest.RevisionComment, opt => opt.MapFrom(src => src.NextRevisionComment));

            Mapper.CreateMap<NewContentDetailModel, Content>()
                .ForMember(dest => dest.ContentTypeName, opt => opt.Ignore())
                .ForMember(dest => dest.PublicationDate, opt => opt.Ignore())
                .ForMember(dest => dest.Publisher, opt => opt.Ignore())
                .ForMember(dest => dest.ApprovalDate, opt => opt.Ignore())
                .ForMember(dest => dest.ApprovalMembershipId, opt => opt.Ignore())
                .ForMember(dest => dest.ContentDataId, opt => opt.Ignore())
                .ForMember(dest => dest.Author, opt => opt.Ignore())
                .ForMember(dest => dest.Id, opt => opt.Ignore())
                .ForMember(dest => dest.Language, opt => opt.Ignore())
                .ForMember(dest => dest.SystemName, opt => opt.Ignore())
                .ForMember(dest => dest.LatestRevisionNumber, opt => opt.Ignore())
                .ForMember(dest => dest.LatestApprovedRevisionNumber, opt => opt.Ignore())
                .ForMember(dest => dest.RevisionNumber, opt => opt.Ignore())
                .ForMember(dest => dest.ExternalId, opt => opt.Ignore())
                .ForMember(dest => dest.CreateDate, opt => opt.Ignore())
                .ForMember(dest => dest.RevisionMembershipId, opt => opt.Ignore())
                .ForMember(dest => dest.CreateMembershipId, opt => opt.Ignore())
                .ForMember(dest => dest.RevisionDate, opt => opt.Ignore())
                .ForMember(dest => dest.Height, opt => opt.Ignore())
                .ForMember(dest => dest.Width, opt => opt.Ignore())
                .ForMember(dest => dest.MimeType, opt => opt.Ignore())
                .ForMember(dest => dest.MimeSubtype, opt => opt.Ignore())
                .ForMember(dest => dest.SiteName, opt => opt.Ignore())
                .ForMember(dest => dest.Url, opt => opt.Ignore())
                .ForMember(dest => dest.IsSecure, opt => opt.Ignore())
                .ForMember(dest => dest.DefaultAuthority, opt => opt.Ignore())

                .ForMember(dest => dest.IsNew, opt => opt.UseValue(true))

                .ForMember(dest => dest.RevisionComment, opt => opt.MapFrom(src => src.NextRevisionComment));

            Mapper.CreateMap<Content, ExistingContentDetailModel>()
                .ForMember(dest => dest.Categories, opt => opt.Ignore())
                .ForMember(dest => dest.SimilarContent, opt => opt.Ignore())
                .ForMember(dest => dest.NextRevisionComment, opt => opt.Ignore());
        }
    }
}
